package com.szxx.suit.softbomb;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.springframework.stereotype.Component;

import com.szxx.constant.DdzCardTypes;
import com.szxx.domain.Card;
import com.szxx.domain.Cards;
import com.szxx.domain.DdzCard;
import com.szxx.suit.AbstractSuitTerm;
import com.szxx.suit.AbstractSuitType;
import com.szxx.suit.DdzAnalysisResult;
import com.szxx.suit.DdzSuitAnalyzer;
import com.szxx.suit.DdzTypeUtil;

/**
 * 炸弹牌型 <br>
 *
 * @author Ambrose
 */
@Component
public class SoftBombTypeAnalyzer extends DdzSuitAnalyzer {

	@Override
	public AbstractSuitType getSuitType() {
		return DdzCardTypes.SOFT_BOMB;
	}

	/** 关键数量 */
	private static int TUPLE_SIZE = 4;
	
	@Override
	public boolean doCheckRule(Cards cards, AbstractSuitTerm term, DdzAnalysisResult result) {
		if (result.getCardNum() == TUPLE_SIZE) {
			if ((result.getLaziCardNum() == 0 && result.getChangedLaziCardNum() == 0)
					|| result.isAllCardLazi()) { // 没有癞子，都是癞子
				return false;
			} else { // 癞子的情况
				if (result.getNoneLaziValueCounter().hasJoker()) { // 非赖中含有大小王
					return false;
				}
				List<Card> cardList = cards.subList(0, result.getNoneCardNum()); // 取出非癞子部分的牌
				int firstCardValue = cardList.get(0).getValue();
				for (int i = 0; i < cardList.size(); i++) {
					if (cardList.get(i).getValue() != firstCardValue) {
						return false;
					}
				}
				return true;
			}
		} else {
			return false;
		}
	}
	
	@Override
	protected List<Cards> doAnalysizeLaizi(Cards cards, AbstractSuitTerm term, boolean onlyMaxValue) {
		List<Cards> cardsResult = new LinkedList<Cards>();
		DdzAnalysisResult result = (DdzAnalysisResult) cards.getResult();
		List<Card> laiziCardList = new ArrayList<Card>(cards.subList(result.getCardNum() - result.getLaziCardNum(), result.getCardNum()));
		int value = result.getNoneLaziValueCounter().getAllValues().get(0).intValue();
		for (Card card : laiziCardList) { // 设置number
			((DdzCard) card).changeCard(value);
		}
		Cards cardsCopy = cards.clone();
		analysize(cardsCopy, term);
		cardsResult.add(cardsCopy);
		return cardsResult;
	}
	
	@Override
	protected boolean containsPossibleCards(Cards handCards, AbstractSuitTerm term) {
		DdzAnalysisResult result = (DdzAnalysisResult) handCards.getResult();
		if (result.getCardNum() >= TUPLE_SIZE) {
			List<Integer> noneLaiziValues = result.getNoneLaziValueCounter().getAllValues();
			int maxValueNum= 0;
			for (Integer valueTemp : noneLaiziValues) {
				int valueTempNum = result.getNoneLaziValueCounter().getValueCount(valueTemp);
				if (valueTempNum > maxValueNum) {
					maxValueNum = valueTempNum;
				}
			}
			// 软炸弹数量足够
			return result.getLaziCardNum() > 0 && result.getLaziCardNum() + maxValueNum >= TUPLE_SIZE;
		} else {
			return false;
		}
	}
	
	/** 最多使用癞子的数量 */
	private static int MAX_USE_LAIZI_CARD_NUM = 3;
	
	@Override
	protected List<Cards> doListPossibleCards(Cards handCards, AbstractSuitTerm term) {
		List<Cards> cardsResult = new LinkedList<Cards>();
		// 非癞子部分
		DdzAnalysisResult result = (DdzAnalysisResult) handCards.getResult();
		List<Card> noneLaiziCardList = handCards.subList(0, result.getNoneCardNum());
		Cards noneLaiziCards = DdzTypeUtil.createCardsCopy(noneLaiziCardList);
		noneLaiziCards.setResult(handCards.getResult().clone());
		// 癞子部分
		List<Card> laiziCardList = handCards.subList(result.getNoneCardNum(), result.getCardNum());
		Cards laiziCards = DdzTypeUtil.createCardsCopy(laiziCardList);
		laiziCards.setResult(handCards.getResult().clone());
		
		int laiziCardNum = result.getLaziCardNum();
		int maxUseLaiziCardNum = MAX_USE_LAIZI_CARD_NUM < laiziCardNum ? MAX_USE_LAIZI_CARD_NUM : laiziCardNum;
		for (int useLaiziCardNum = 1; useLaiziCardNum <= maxUseLaiziCardNum; useLaiziCardNum++) {
			List<Card> useLaiziCardList = DdzTypeUtil.cloneSublistedCards(laiziCards, 0, useLaiziCardNum);// 补癞子
			int needCardNum = TUPLE_SIZE - useLaiziCardNum;
			List<Cards> cardsList = new LinkedList<Cards>();
			if (needCardNum == 1) {
				cardsList.addAll(DdzTypeUtil.selectSingleCards(noneLaiziCards, false));
			} else {
				cardsList.addAll(DdzTypeUtil.selectTupleCountCards(noneLaiziCards, needCardNum));
			}
			for (Cards usecards : cardsList) {
				Card card = usecards.get(0);
				for (Card laiziCard : useLaiziCardList) {
					((DdzCard)laiziCard).changeCard(card.getValue());
				}
				Cards cardsCopy = DdzTypeUtil.cloneCardsAndAddCardList(usecards, useLaiziCardList);
				if (match(cardsCopy, term)) {
					analysize(cardsCopy, term);
					cardsResult.add(cardsCopy);
				}
			}
		}
		return cardsResult;
	}

}
